package com.edfu.core.identitymgt.persistence.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import com.edfu.core.identitymgt.persistence.api.IIdentityMgtPersistence;
import com.edfu.core.identitymgt.persistence.entity.IIdentityMgtEntity;
import com.edfu.core.identitymgt.persistence.entity.PermissionEntity;
import com.edfu.core.identitymgt.persistence.entity.RoleEntity;
import com.edfu.core.identitymgt.persistence.entity.RolePermissionEntity;
import com.edfu.core.identitymgt.persistence.entity.UserEnrollmentEntity;
import com.edfu.core.identitymgt.persistence.entity.UserEntity;
import com.edfu.core.identitymgt.vo.Permission;
import com.edfu.core.identitymgt.vo.RolePermission;

public class IdentityMgtPersistenceImpl implements IIdentityMgtPersistence {

	private EntityManager entityManager;
	@PersistenceContext
	public void setEntityManager(EntityManager entityManager) {
		this.entityManager = entityManager;
	}
	
	@Override
	public UserEntity getUser(String userId) {
		Query q = entityManager.createQuery("select u from UserEntity u where userId = :userId");
		q.setParameter("userId", userId);
		List<?> usersList = q.getResultList();
		if ( usersList == null || usersList.size() == 0)
			return null ;
		else
			return (UserEntity) usersList.get(0);
	}
	
	@Override
	public RoleEntity getRole(String roleName) {
		Query q = entityManager.createQuery("select e from RoleEntity e where e.name = :roleName");
		q.setParameter("roleName", roleName);
		List<?> resultList = q.getResultList();
		if (resultList == null || resultList.size() == 0)
			return null ;
		else 
			return (RoleEntity)resultList.get(0);
	}

	@Override
	public void persist(IIdentityMgtEntity entity) {
		entityManager.persist(entity);
	}

	@Override
	public UserEnrollmentEntity getUserEnrollment(String userId, String roleName) {
		Query q = entityManager.createQuery("select e from UserEnrollmentEntity e where e.user.userId = :userId and e.role.name= :roleName"); 
		q.setParameter("userId", userId);
		q.setParameter("roleName", roleName);
		List<?> resultList = q.getResultList();
		if (resultList == null || resultList.size() == 0) {
			return null;
		}else {
			return (UserEnrollmentEntity) resultList.get(0);
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<UserEnrollmentEntity> getRoles(String userId) {
		List<UserEnrollmentEntity> resultList = null;
		try{
		Query q = entityManager.createQuery("select e from UserEnrollmentEntity e where e.user.userId = :userId"); 
		q.setParameter("userId", userId);
		resultList = q.getResultList();
		} catch (Throwable t) {
			t.printStackTrace();
			throw new RuntimeException(t.getMessage());
		}
		if (resultList == null || resultList.size() == 0) {
			return null;
		}else {
			return resultList;
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public PermissionEntity getPermission(Permission permission) {
		if (permission.getId() != 0) {
			return entityManager.find(PermissionEntity.class, permission.getId());
		}
		Query query = entityManager.createQuery("select p from PermissionEntity p where p.name = :permissionName");
		query.setParameter("permissionName", permission.getName());
		
		List<PermissionEntity> entityList = query.getResultList();
		PermissionEntity pe = null;
		
		if (entityList != null && entityList.size() > 0) {
			pe = entityList.get(0);
		}
		 
		return pe;	
	}

	@Override
	public void assignPermission(RolePermission rolePermission) {
		PermissionEntity pe = getPermission(rolePermission.getPermission());
		RoleEntity re = getRole(rolePermission.getRole().getName());
		RolePermissionEntity rpe = new RolePermissionEntity();
		rpe.setRole(re);
		rpe.setPermission(pe);
		
		entityManager.persist(rpe);
	}

	@SuppressWarnings("unchecked")
	@Override
	public Collection<? extends PermissionEntity> getPermissions(RoleEntity role) {
		Collection<PermissionEntity> permissions = new ArrayList<PermissionEntity>();
		Query query = entityManager.createQuery("select r from RolePermissionEntity r where r.role = :roleEntity");
		query.setParameter("roleEntity", role);
		
		List<RolePermissionEntity> rpeList = query.getResultList();
		
		if (rpeList != null && rpeList.size() > 0) {
			for (RolePermissionEntity rpe : rpeList) {
				permissions.add(rpe.getPermission());
			}
		}
		
		return permissions;
	}
	
}
